<template>
  <div
    class="token"
    @click="handleClick"
    @mouseenter="onMouseEnter"
    @mouseleave="onMouseLeave"
    :class="[role.id]"
    :disabled="disableClick"
    ref="tokenElement"
  >
    <img
      v-if="role.id"
      class="icon"
      :src="iconUrl"
      @load="onImageLoad"
      @error="onImageError"
      :alt="role.name || role.id"
    />
    <span
      class="leaf-left"
      v-if="role.firstNight || role.firstNightReminder"
    ></span>
    <span
      class="leaf-right"
      v-if="role.otherNight || role.otherNightReminder"
    ></span>
    <span v-if="reminderLeaves" :class="['leaf-top' + reminderLeaves]"></span>
    <span class="leaf-orange" v-if="role.setup"></span>
    <svg viewBox="0 0 150 150" class="name">
      <path
        d="M 13 75 C 13 160, 138 160, 138 75"
        id="curve"
        fill="transparent"
      />
      <text
        width="150"
        x="66.6%"
        text-anchor="middle"
        class="label mozilla"
        :font-size="role.name | nameToFontSize"
      >
        <textPath xlink:href="#curve">
          {{ role.name }}
        </textPath>
      </text>
    </svg>
    <div class="edition" :class="[`edition-${role.edition}`, role.team]"></div>
    <div class="ability" v-if="role.ability && showTooltip" ref="abilityTooltip">
      {{ role.ability }}
    </div>
    <!-- 待处决状态骷髅头图标 -->
    <div v-if="isNominated" class="execution-skull">
      <font-awesome-icon icon="skull" />
    </div>
  </div>
</template>

<script>
import { mapState } from "vuex";

export default {
  name: "Token",
  props: {
    role: {
      type: Object,
      default: () => ({}),
    },
    disableClick: {
      type: Boolean,
      default: false,
    },
    allowParentClick: {
      type: Boolean,
      default: false,
    },
    isNominated: {
      type: Boolean,
      default: false,
    },
  },
  computed: {
    reminderLeaves: function () {
      return (
        (this.role.reminders || []).length +
        (this.role.remindersGlobal || []).length
      );
    },
    iconUrl() {
      console.log(`=== Token组件 iconUrl计算 ===`);
      console.log(`角色ID: ${this.role.id}`);
      console.log(`角色名称: ${this.role.name}`);
      console.log(`角色对象:`, this.role);
      console.log(`role.id类型:`, typeof this.role.id);
      console.log(`role.id是否为null:`, this.role.id === null);
      console.log(`role.id是否为undefined:`, this.role.id === undefined);
      console.log(`role.id是否为falsy:`, !this.role.id);
      console.log(`isImageOptIn:`, this.grimoire.isImageOptIn);
      console.log(`useFallbackIcon:`, this.useFallbackIcon);

      // 如果图片加载失败，使用默认图标
      if (this.useFallbackIcon) {
        console.log(`使用默认图标 for role: ${this.role.id}`);
        return this.getFallbackIconUrl();
      }

      // 如果有自定义图片且启用了自定义图片
      if (this.role.image && this.grimoire.isImageOptIn) {
        console.log(
          `加载自定义图片 for role ${this.role.id}:`,
          this.role.image,
        );
        return this.role.image;
      }

      // 使用默认图标路径
      const defaultIconUrl = require(`../assets/icons/${this.role.id}.png`);
      console.log(`使用默认图标路径:`, defaultIconUrl);
      return defaultIconUrl;
    },
    ...mapState(["grimoire"]),
  },
  data() {
    return {
      imageLoaded: false,
      imageError: false,
      useFallbackIcon: false,
      showTooltip: false, // 控制提示框显示状态
    };
  },
  filters: {
    nameToFontSize: (name) => (name && name.length > 10 ? "90%" : "110%"),
  },
  methods: {
    handleClick() {
      if (!this.disableClick) {
        this.$emit("set-role");
      } else if (this.allowParentClick) {
        // 如果禁用了点击但允许父组件点击，则触发父组件的点击事件
        this.$emit("click");
      }
    },
    onImageLoad() {
      this.imageLoaded = true;
      this.imageError = false;
      console.log(`Image loaded successfully for role: ${this.role.id}`);
    },
    onImageError() {
      this.imageError = true;
      this.imageLoaded = false;
      this.useFallbackIcon = true;
      console.error(
        `Failed to load image for role: ${this.role.id}, falling back to default icon`,
      );
      // 强制重新渲染以使用默认图标
      this.$nextTick(() => {
        this.$forceUpdate();
      });
    },
    onMouseEnter() {
      if (this.role.ability) {
        console.log('Mouse enter - role has ability:', this.role.ability);
        this.showTooltip = true;
        console.log('showTooltip set to true');
        this.$nextTick(() => {
          console.log('$nextTick - positioning tooltip');
          this.positionTooltip();
          this.moveTooltipToBody(); // 将提示框移到body层级
        });
      } else {
        console.log('Mouse enter - no ability for role:', this.role.id);
      }
    },
    onMouseLeave() {
      console.log('Mouse leave - hiding tooltip');
      this.showTooltip = false;
    },
    positionTooltip() {
      console.log('positionTooltip called');
      if (!this.$refs.tokenElement || !this.$refs.abilityTooltip) {
        console.log('Missing refs:', {
          tokenElement: !!this.$refs.tokenElement,
          abilityTooltip: !!this.$refs.abilityTooltip
        });
        return;
      }
      
      const token = this.$refs.tokenElement;
      const tooltip = this.$refs.abilityTooltip;
      const tokenRect = token.getBoundingClientRect();
      
      console.log('Token rect:', tokenRect);
      console.log('Tooltip element:', tooltip);
      
      // 计算提示框的理想位置（在token右侧）
      let left = tokenRect.right + 10; // token右侧 + 10px间距
      let top = tokenRect.top + (tokenRect.height / 2) - 50; // 垂直居中对齐
      
      // 获取视口尺寸
      const viewportWidth = window.innerWidth;
      const viewportHeight = window.innerHeight;
      
      // 检查右侧是否有足够空间，如果没有则显示在左侧
      if (left + 300 > viewportWidth) {
        left = tokenRect.left - 310; // token左侧 - 提示框宽度 - 10px间距
      }
      
      // 检查垂直位置，确保不超出视口
      if (top < 10) {
        top = 10; // 距离顶部至少10px
      } else if (top + 100 > viewportHeight) {
        top = viewportHeight - 110; // 距离底部至少10px
      }
      
      console.log('Final position:', { left, top });
      
      // 应用位置
      tooltip.style.left = `${left}px`;
      tooltip.style.top = `${top}px`;
      
      console.log('Tooltip positioned at:', tooltip.style.left, tooltip.style.top);
    },
    moveTooltipToBody() {
      if (this.$refs.abilityTooltip && this.$refs.abilityTooltip.parentNode !== document.body) {
        console.log('Moving tooltip to body');
        // 先从当前位置移除
        if (this.$refs.abilityTooltip.parentNode) {
          this.$refs.abilityTooltip.parentNode.removeChild(this.$refs.abilityTooltip);
        }
        // 添加到body，确保脱离所有容器限制
        document.body.appendChild(this.$refs.abilityTooltip);
        
        // 给tooltip添加特殊class，应用portal样式
        this.$refs.abilityTooltip.classList.add('tooltip-portal');
        console.log('Tooltip moved to body successfully');
      }
    },
    getFallbackIconUrl() {
      // 确定要使用的图标名称
      let iconName = this.role.imageAlt || this.role.id;

      // 确保图标名称是有效的本地图标
      const validIcons = [
        "good",
        "outsider",
        "minion",
        "evil",
        "fabled",
        "custom",
        "imp",
        "witch",
        "widow",
        "washerwoman",
        "voudon",
        "vortox",
        "virgin",
        "vigormortis",
        "undertaker",
        "toymaker",
        "towncrier",
        "tinker",
        "thief",
        "tealady",
        "sweetheart",
        "stormcatcher",
        "spy",
        "spiritofivory",
        "soldier",
        "snitch",
        "snakecharmer",
        "slayer",
        "shabaloth",
        "sentinel",
        "seamstress",
        "scarletwoman",
        "scapegoat",
        "savant",
        "saint",
        "sailor",
        "sage",
        "riot",
        "revolutionary",
        "recluse",
        "ravenkeeper",
        "puzzlemaster",
        "pukka",
        "psychopath",
        "professor",
        "preacher",
        "poppygrower",
        "politician",
        "poisoner",
        "po",
        "plus",
        "pixie",
        "pithag",
        "philosopher",
        "pacifist",
        "oracle",
        "nodashii",
        "noble",
        "nightwatchman",
        "mutant",
        "moonchild",
        "monk",
        "minstrel",
        "mezepheles",
        "mephit",
        "mayor",
        "matron",
        "mathematician",
        "mastermind",
        "marionette",
        "magician",
        "lycanthrope",
        "lunatic",
        "lleech",
        "lilmonsta",
        "librarian",
        "leviathan",
        "legion",
        "klutz",
        "king",
        "juggler",
        "judge",
        "investigator",
        "innkeeper",
        "huntsman",
        "heretic",
        "hellslibrarian",
        "harlot",
        "gunslinger",
        "grandmother",
        "gossip",
        "goon",
        "golem",
        "godfather",
        "goblin",
        "general",
        "gangster",
        "gambler",
        "fortuneteller",
        "fool",
        "flowergirl",
      ];

      // 如果图标名称不在有效列表中，使用基于团队的默认图标
      if (!validIcons.includes(iconName)) {
        console.warn(
          `Invalid icon name: ${iconName} for role: ${this.role.id}, using team-based fallback`,
        );
        iconName =
          {
            townsfolk: "good",
            outsider: "outsider",
            minion: "minion",
            demon: "evil",
            fabled: "fabled",
          }[this.role.team] || "custom";
      }

      try {
        return require(`../assets/icons/${iconName}.png`);
      } catch (error) {
        console.error(
          `Failed to load icon: ${iconName}.png for role: ${this.role.id}`,
          error,
        );
        // 最后的回退方案
        return require("../assets/icons/custom.png");
      }
    },
  },
  mounted() {
    // 组件挂载时重置图片状态
    console.log(`Token mounted for role: ${this.role.id}`);
    this.imageLoaded = false;
    this.imageError = false;
    this.useFallbackIcon = false;
  },
  beforeDestroy() {
    // 组件销毁时清理tooltip
    this.showTooltip = false;
    if (this.$refs.abilityTooltip && this.$refs.abilityTooltip.parentNode === document.body) {
      document.body.removeChild(this.$refs.abilityTooltip);
    }
  },
  watch: {
    "role.image": {
      handler() {
        // 当角色图片变化时，重置图片状态并强制重新计算
        console.log(`Role image changed for ${this.role.id}:`, this.role.image);
        this.imageLoaded = false;
        this.imageError = false;
        this.useFallbackIcon = false;
        this.$nextTick(() => {
          this.$forceUpdate();
        });
      },
      immediate: true,
    },
    "grimoire.isImageOptIn": {
      handler() {
        // 当图片显示设置变化时，重置图片状态并强制重新计算
        console.log(`Image opt-in changed:`, this.grimoire.isImageOptIn);
        this.imageLoaded = false;
        this.imageError = false;
        this.useFallbackIcon = false;
        this.$nextTick(() => {
          this.$forceUpdate();
        });
      },
      immediate: true,
    },
    "role.id": {
      handler() {
        // 当角色ID变化时，重置图片状态
        console.log(`Role ID changed:`, this.role.id);
        this.imageLoaded = false;
        this.imageError = false;
        this.useFallbackIcon = false;
        this.$nextTick(() => {
          this.$forceUpdate();
        });
      },
      immediate: true,
    },
  },
};
</script>

<style scoped lang="scss">
.token {
  border-radius: 50%;
  width: 100%;
  background: url("../assets/token.png") center center;
  background-size: 100%;
  text-align: center;
  border: 3px solid black;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 300ms cubic-bezier(0.4, 0, 0.2, 1);
  transform: scale(1);

  &[disabled="true"] {
    pointer-events: none;
  }

  &:hover {
    transform: scale(1.05);
    box-shadow: 0 0 20px rgba(0, 0, 0, 0.7);
  }

  &:hover .name .label {
    stroke: black;
    fill: white;
    @-moz-document url-prefix() {
      &.mozilla {
        stroke: none;
        filter: drop-shadow(0 1.5px 0 black) drop-shadow(0 -1.5px 0 black)
          drop-shadow(1.5px 0 0 black) drop-shadow(-1.5px 0 0 black)
          drop-shadow(0 2px 2px rgba(0, 0, 0, 0.5));
      }
    }
  }

  .icon {
    position: absolute;
    width: 100%;
    height: 100%;
    object-fit: contain;
    object-position: center 30%;
    margin-top: 3%;
    pointer-events: none;
  }

  span {
    position: absolute;
    width: 100%;
    height: 100%;
    background-size: 100%;
    pointer-events: none;

    &.leaf-left {
      background-image: url("../assets/leaf-left.png");
    }

    &.leaf-orange {
      background-image: url("../assets/leaf-orange.png");
    }

    &.leaf-right {
      background-image: url("../assets/leaf-right.png");
    }

    &.leaf-top1 {
      background-image: url("../assets/leaf-top1.png");
    }

    &.leaf-top2 {
      background-image: url("../assets/leaf-top2.png");
    }

    &.leaf-top3 {
      background-image: url("../assets/leaf-top3.png");
    }

    &.leaf-top4 {
      background-image: url("../assets/leaf-top4.png");
    }

    &.leaf-top5 {
      background-image: url("../assets/leaf-top5.png");
    }
  }

  .name {
    width: 100%;
    height: 100%;
    font-size: 24px; // svg fonts are relative to document font size

    // 确保SVG内的所有元素都不阻止点击事件
    svg {
      pointer-events: none;
    }

    path {
      pointer-events: none;
    }

    text {
      pointer-events: none;
    }

    textPath {
      pointer-events: none;
    }

    .label {
      fill: black;
      stroke: white;
      stroke-width: 2px;
      paint-order: stroke;
      font-family: "Papyrus", serif;
      font-weight: bold;
      text-shadow: 0 2px 2px rgba(0, 0, 0, 0.2);
      letter-spacing: 1px;
      pointer-events: none; // 确保文本元素也不阻止点击

      @-moz-document url-prefix() {
        &.mozilla {
          // Vue doesn't support scoped media queries, so we have to use a second css class
          stroke: none;
          text-shadow: none;
          filter: drop-shadow(0 1.5px 0 white) drop-shadow(0 -1.5px 0 white)
            drop-shadow(1.5px 0 0 white) drop-shadow(-1.5px 0 0 white)
            drop-shadow(0 2px 2px rgba(0, 0, 0, 0.5));
        }
      }
    }
  }

  .edition {
    position: absolute;
    right: 0;
    bottom: 5px;
    width: 30px;
    height: 30px;
    background-size: 100%;
    display: none;
  }

  .ability {
    display: flex;
    position: fixed; // 使用fixed定位，完全脱离容器限制
    padding: 5px 10px;
    width: 250px;
    z-index: 999999 !important; // 最高层级，强制覆盖所有其他元素
    font-size: 80%;
    background: rgba(0, 0, 0, 0.9); // 进一步增加背景不透明度
    border-radius: 10px;
    border: 3px solid black;
    filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.8));
    text-align: left;
    justify-items: center;
    align-content: center;
    align-items: center;
    pointer-events: none;
    opacity: 1; // 始终可见，通过v-if控制显示
    transition: opacity 200ms ease-in-out;
    
    // 创建独立的层叠上下文，确保不被任何元素遮挡
    transform: translateZ(0) !important;
    will-change: transform;
    isolation: isolate !important;
    contain: layout style !important;
    
    // 强制突破所有容器限制
    position: fixed !important;
    clip-path: none !important;
    mask: none !important;
    overflow: visible !important;
    
    // 提示框的最大宽度和自适应
    max-width: 300px;
    min-width: 200px;
    word-wrap: break-word;
    white-space: normal;
    
    // JavaScript会动态设置正确位置
    top: 0;
    left: 0;

    &:before {
      content: " ";
      border: 10px solid transparent;
      width: 0;
      height: 0;
      border-right-color: black;
      position: absolute;
      margin-right: 2px;
      right: 100%;
    }
  }

  // hover样式已由JavaScript控制，此处注释
  // &:hover .ability {
  //   opacity: 1;
  // }

  .execution-skull {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    z-index: 10;

    svg {
      height: 60%;
      width: 60%;
      stroke: white;
      stroke-width: 15px;
      filter: drop-shadow(0px 0px 6px black);

      path {
        fill: white;
      }
    }
  }
}

/* Portal tooltip样式 - 当tooltip被移动到body时的特殊样式 */
.tooltip-portal.ability {
  position: fixed !important;
  z-index: 9999999 !important;
  pointer-events: none !important;
  
  /* 强制脱离所有容器限制 */
  transform: translateZ(0) translate3d(0,0,0) !important;
  will-change: transform, opacity !important;
  isolation: isolate !important;
  contain: none !important;
  clip-path: none !important;
  mask: none !important;
  overflow: visible !important;
  
  /* 确保不受任何父容器影响 */
  margin: 0 !important;
  padding: 5px 10px !important;
  float: none !important;
  clear: none !important;
  
  /* 视觉样式 */
  background: rgba(0, 0, 0, 0.95) !important;
  border: 3px solid #fff !important;
  border-radius: 10px !important;
  filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.8)) !important;
  
  /* 确保在最顶层 */
  transform-style: preserve-3d !important;
  backface-visibility: visible !important;
}
</style>
